home *** CD-ROM | disk | FTP | other *** search
/ Monster Media 1994 #2 / Monster Media No. 2 (Monster Media)(1994).ISO / prog_gen / xv_pc16a.zip / XVIEW_PC.TXT < prev    next >
Text File  |  1994-04-26  |  36KB  |  706 lines

  1. XView-PC: Graphical User Interface for Turbo C and Turbo Pascal
  2. ---------------------------------------------------------------
  3.  
  4. By:
  5. Antonio Carlos Moreirao de Queiroz
  6. Department of Electronic Engineering and COPPE
  7. Federal University of Rio de Janeiro, Brazil
  8. e-mail: acmq@coe.ufrj.br
  9.  
  10. INTRODUCTION
  11. ------------
  12.  
  13.   The XView-PC graphical user interface attempts to be similar to the XView
  14. toolkit used in Sun workstations, in a simplified from.
  15.   It can be used in Pascal, C, or C++ versions. The interface is the same in
  16. any of the versions, with minor differences in the Pascal version.
  17.   The interface was initially developed as an intermediate step in porting
  18. programs from the PC to Sun workstations, by implementing a subset of the
  19. Sun XView toolkit in the PC. The work was not completed because it soon
  20. become clear that a total translation would be unnecessarily complex. Even
  21. so, the working of the two interfaces was kept similar when reasonable.
  22.   What can be done with the interface in its present form can be repeated
  23. with the Sun XView without significant structural changes, although with
  24. differences due to the various simplifications made. The porting of an
  25. application to Windows is also not complex.
  26.   The interface code is of simple use and adds only about 25 k to the
  27. executable program doing all the user interface functions. It works with any
  28. PC compatible computer, in any graphics mode supported by the BGI drivers and
  29. installed mouse driver. If a mouse is not installed, a mouse emulator using
  30. the keyboard is automatically used.
  31.   To simplify the interface code generation, an interface editor program,
  32. X_MAKE.EXE, is included. It allows the edition of a complete user
  33. interface, and the automatic generation of an skeleton program in Pascal or
  34. C, that is a fully functional program that the user can edit and complete.
  35.  
  36. TYPICAL PROGRAM STRUCTURE
  37. -------------------------
  38.  
  39.   Below is the structure of a typical program using the interface:
  40.  
  41. - Program header:
  42. - Declaration of global variables and interface "objects".
  43. - Normal subroutines.
  44. - Subroutines called from the interface objects ("callbacks").
  45. - Main program:
  46. - Normal initialization.
  47. - Interface initialization: call to "xv_init".
  48. - Creation and initialization of the interface objects: calls to
  49.   "xv_create" followed by direct initialization of the object parameters.
  50. - Passing of control to the interface "notifier": call to "xv_main_loop".
  51. - Normal termination.
  52.  
  53. INTERFACE OBJECTS
  54. -----------------
  55.  
  56.   The user interface is composed of "objects". Note that the interface was
  57. not programmed with "object-oriented" specific techniques, but some ideas
  58. are used.
  59.   There are eight types of predefined objects, listed below. Their names
  60. are the parameters to be passed to the "xv_create" procedure.
  61.  
  62. - "frame":     Base windows, where the other objects are.
  63. - "button":    Command buttons.
  64. - "textfield": Input fields for text and numerical values, with edition.
  65. - "setting":   Input fields for logical values (choices).
  66. - "message":   Messages or icons in the windows.
  67. - "canvas":    Graphical output subwindows.
  68. - "tty":       Text output subwindows.
  69. - "menu":      Pop-up menus.
  70.  
  71.   Other types of objects can be programmed, if necessary, by adding the
  72. desired functionality to "canvas" objects through their "callback"
  73. routines. See the example program ROTOR.PAS.
  74.  
  75. EVENT-ORIENTED PROGRAMMING
  76. --------------------------
  77.  
  78.   The interface is intended to be used in an event-oriented program. The
  79. basic ideas are:
  80.  
  81.   The program does not follow a predefined fluxogram, but is commanded by
  82. the user, that generates "events" by acting on the objects in the windows,
  83. what causes calls to the "callback" routines, where the program functional
  84. code is located.
  85.   Any "callback" subroutine can be called at any moment. In its initial
  86. code, it can be necessary for the routine to check the program status to
  87. determine what is to be done. The program status can be maintained in a set
  88. of global logical variables, and/or in the "textfield", "setting", and
  89. "menu" objects.
  90.   The "callback" routines have complete control of the machine while active.
  91. They can open or close windows using "open_window" and "close_window",
  92. draw in "canvas" objects using the normal graphical functions, print
  93. messages in "tty" (using "ttysw_output") or "message" objects (using
  94. "xv_set"), or anything else that does not corrupt the interface structures.
  95.   The user is never prompted for information in a way that blocks the
  96. program execution (it is possible, if necessary, through windows with
  97. exclusive access (see the file EXCLUSIV.INC), but not recommended). The
  98. procedure for getting information from the user is to open a window with
  99. items to filled. "Callback" routines associated with the window objects
  100. update the program status and continue the execution, when and if the user
  101. commands.
  102.   The program never reads the keyboard or mouse directly (it is possible,
  103. using the normal functions and the MICKEY module functions, but also not
  104. recommended). All the inputs from the user are received as events and actions
  105. on the objects.
  106.  
  107.   The objects call "callback" routines by three mechanisms, associated with
  108. the object attributes:
  109.  
  110. "notify_handler": A "callback" routine, called when:
  111. - "frame": The window is closed.
  112. - "texfield": The return key is pressed, at the end of an edition.
  113. - "canvas": The window is redrawn, on the opening and resizing of the
  114.   window.
  115. - Other objects: The left mouse button is pressed over the object.
  116.  
  117. "event_handler": A "callback" routine, called when the state of the mouse
  118. changes over the object, or when a key is pressed, with the mouse pointer
  119. over the object.
  120.  
  121. "menu_name": Name of a "menu", opened with the right mouse button pressed
  122. over the object. The menus normally have an associated "notify handler",
  123. called when a selection is done. It is also possible to open a menu
  124. programatically, using the "menu_show" procedure. The items of a menu can
  125. have an associated "item_submenu" (name of another menu),also opened with
  126. the right mouse button. The same is valid for submenus of any order. The
  127. left mouse button always cause the selection of the present item, even if
  128. there are submenus. The central mouse button (or both right and left
  129. buttons simultaneously) cause the dismiss of menus without a call to the
  130. menu "notify_handler".
  131.  
  132.   The "callback" routines have always the same structure. They are far
  133. procedures receiving a single argument, that is the calling object pointer.
  134. Using this pointer, the parameters of the calling object can be accessed.
  135.  
  136. EVENTS
  137. ------
  138.  
  139.   The "event_handler" routines can read the event that caused the call in
  140. the global variable "ie_code". Its meanings are:
  141.  
  142. - Mouse events: "ie_code" contains:
  143.   LOC_MOVE: Movement.
  144.   LOC_DRAG: Movement with some button pressed.
  145.   MS_LEFT: Left button pressed.
  146.   MS_MIDDLE: Central button pressed.
  147.   MS_RIGHT: Right button pressed.
  148.   The state of the mouse buttons (as returned by the DOS interrupt 33) is in
  149. the global variable "ie_shiftcode".
  150.   The event names above are predefined constants. In the general case for
  151. button events, "ie_code"=1000+10*<buttons before>+<buttons after>.
  152.   The mouse position, relative to the object upper left corner, is in the
  153. global variables "ie_locx" and "ie_locy". The absolute mouse position is also
  154. available in the variables "mousex" and "mousey", defined in the MICKEY
  155. module.
  156.  
  157. - Keyboard events: "ie_code" contains the ASCII code of the pressed key. In
  158. the case of keys with extended codes, "ie_code" contains 2000+2nd code.
  159. With the mouse emulator in operation (see the MOUSE DRIVER section), events
  160. that are used by the emulator are not generated, unless the ScrollLock key is
  161. active, what returns the keyboard to normal operation.
  162.  
  163.   Some events interpreted by the interface are not passed to the
  164. "event_handlers". Only the "canvas" objects receive all the events. In any
  165. way, there is no much sense in detecting events over other objects.
  166.  
  167. WINDOWS
  168. -------
  169.  
  170.   There is always an active window, which "frame" pointer is equal to  the
  171. global variable "active_w". The active window is the last opened by the
  172. program, or where a button mouse was pressed most recently.
  173.   To press a mouse key over a window partially covered causes its movement
  174. to the foreground before the processing of the event. The procedures
  175. "open_window", "close_window", "xv_set", "ttysw_output", and "xv_main_loop"
  176. also move their parameter window to the foreground and turn them into the
  177. active window.
  178.   Windows are closed with the procedure "close_window", or by pressing the
  179. central mouse button in the header or an empty area of the window.
  180. The "frame" parameter "adjust_exit" controls if the window can be closed by
  181. the central mouse button. To press simultaneously the right and left mouse
  182. buttons has the same effect.
  183.   Windows are always movable and resizable. Their minimum sizes are
  184. controlled by the "frame" parameters "dxmin" and "dymin". If the window
  185. contains objects with bitmaps or "tty" and "canvas" objects, these values
  186. shall be set to a value high enough to impede the window to be reduced
  187. below the size needed for these objects. The default minimum sizes are
  188. dxmin=99 and dymin=99 (100x100 pixels).
  189.   Objects of type "canvas" and "tty" can change in size to accommodate
  190. changes in their window sizes. This behavior can be controlled by the
  191. parameters "canvas_xext", "canvas_yext", "tty_xext", and "tty_yext", that
  192. control if the objects extend to the window right and bottom edges. As
  193. default, they do it.
  194.  
  195. GRAPHICAL OUTPUT
  196. ----------------
  197.  
  198.   Usually, graphical output is created with the normal Pascal and C
  199. procedures and functions, called from the "callback" routines. When the
  200. "callbacks" are called, the "viewport" is set to the last "canvas" of the
  201. active window, or by the active area of the active window if there is no
  202. "canvas" on it. It is possible to change the "viewport" to draw in other
  203. areas, but usually it is not necessary. The present "viewport" is contained
  204. in the parameter "gr_out" of the active window. When it points to a "canvas"
  205. area, there is a 1 pixel margin for the "canvas" border, so the usable area
  206. is from (0,0) to (dx-2,dy-2), where "dx" and "dy" are the canvas width and
  207. height parameters.
  208.   The mouse support is totally transparent. It is not necessary to turn off
  209. the mouse cursor to draw, as the "callbacks" are always called with the
  210. cursor off.
  211.   The simplest way of generating drawings correctly is from the "canvas"
  212. notify and event handlers. The "notify_handler" is called when the window
  213. is opened or resized. The code in it shall be able to reproduce the entire
  214. drawing, usually scaled to the window dimensions. The "event_handler" can
  215. cause editing functions in a drawing, provide cursor functions, etc.
  216.   Frequently it is desirable to draw in a "canvas" from other "callbacks".
  217. It is possible if the window containing the "canvas" is first turned into
  218. the active window.
  219.   There is no problem when the owner of the "callback" belongs to the same
  220. window, or to a menu called from a window object. If it is not the case,
  221. the "canvas" window can be activated with a call to "open_window". The
  222. operation can be impossible due to memory limitations, and so after the
  223. call the global boolean variable "xv_ok" shall be tested before any drawing
  224. operation.
  225.   It is frequently useful also to call a "canvas" "notify_handler" from
  226. another "callback" to cause a complete redrawing. The "canvas" window must
  227. be the active window for correct results. Note that a call to "open_window"
  228. when the window is not in the screen causes a call to the "canvas"
  229. "notify_handler". So, if the "canvas" window is not in the screen, the call
  230. to the "notify_handler" after the call to "open_window" is not necessary
  231. (it would cause two redrawings).
  232.   If the canvas window is on the screen (the "frame" attribute "mapped"
  233. contains this information), a safe procedure is to close all the windows
  234. that are above it before drawing. In Pascal, the code for this is:
  235. WHILE not active_w = <desired window "frame"> DO close_window(active_w);
  236.   If a "callback" routine changes the graphical configuration (LineStyle,
  237. TextStyle, etc.) and calls a procedure that draws interface objects, as
  238. "open_window" or "ttysw_output" (not recommended), it must replace the
  239. configuration as it was before the call (the initial defaults).
  240.   Only one "canvas" shall be put in each window, or only the last defined
  241. one will be automatically accessible. See the ROTOR.PAS example to see how
  242. multiple "canvas" objects can be used in the same window.
  243.  
  244. TEXT OUTPUT
  245. -----------
  246.  
  247.   The procedure "ttysw_output" draws text in "tty" objects. The "tty"
  248. window is opened automatically. The procedure can be called from anywhere
  249. in the program. All the written text is stored in a buffer, and can be
  250. reviewed using the "tty" scrollbar. To read the buffer: The text starts at
  251. "bstart" and ends at "tend"-1. The buffer is circular, with the position "0"
  252. coming after the position "bsize".
  253.  
  254. BITMAP IMAGES
  255. -------------
  256.  
  257.   Objects of types "button" and "message" can display a bitmap image
  258. instead of a text label. If the parameter "icon_label" or "icon_msg" is
  259. set, the parameter "xv_label" is interpreted as the name of a file
  260. containing the image, that is loaded and plotted when the object is drawn.
  261. The supported format is the Windows BMP format, in 16 colors. If the global
  262. variable "use_palette" is set (default), the palette in the VGA screen is
  263. set to the palette in the bitmap. Note that the default Windows palette is
  264. not the same used in Turbo Pascal and C. The gray shade is darker, for
  265. example, so it may be necessary to change some of the default colors of the
  266. interface objects if Windows bitmaps are used. Bitmaps cannot have more
  267. than 640 pixels horizontally, and a "frame" containing bitmap objects must
  268. be big enough to contain the complete images. The bitmap plotting routine
  269. used internally, "drawbitmap", is available for other uses.
  270.  
  271. INTERPOSITION
  272. -------------
  273.  
  274.   It is possible to install an "interposer" procedure, called after each
  275. event, before the determination of the mouse cursor location. It is a special
  276. "callback" routine without parameters, and that is called with the cursor on.
  277.   The interposer routine can modify the event and the mouse position, open
  278. and close windows, open a menu, etc. It is necessary to turn off the cursor
  279. before calls to "open_window" or "ttysw_output", calling "cursor_off" (MICKEY
  280. module). It is not necessary to turn on the cursor on exit.
  281.   The "interposer" can implement utilities as "accelerator keys" (see modules
  282. hotkeys.int and tabkeys.int), help, event filtering, etc.
  283.   To activate: insert "interposer:=<procedure>;" somewhere after "xv_init".
  284.   To inactivate: "interposer:=nointerpose;"
  285.   Events generated in internal operations, as while a "textfield" is in
  286. edition, are not passed to the "interposer".
  287.  
  288. MEMORY USAGE
  289. ------------
  290.  
  291.   In the normal usage, the objects are allocated at the beginning of the
  292. program execution, and are kept until the end. Dynamic allocation is also
  293. possible. All the memory used for the interface objects is allocated in the
  294. heap. In Turbo Pascal 7, in protected mode, the heap can use all the
  295. available extended (XMS) memory. The needed .TPP units are included in the
  296. XV_PC*.ZIP file.
  297.   Window movement and reordering use additional memory, freed at the end of
  298. the operation. Window operations that need more memory than the available
  299. are refused, and a "beep" sounds. The global variable "xv_ok" turns into
  300. false or 0 when this occur. Programs shall avoid to put big windows above
  301. other windows, to minimize memory use. Large windows shall be put directly
  302. over the background.
  303.  
  304.   The objects allocate the amounts of heap memory listed below (Pascal
  305. version):
  306. - "SizeOf(xv_widget)" bytes (262).
  307. - The size of the strings used in the "menu" and "setting" items (Pascal only).
  308. - The size of the buffer used in "tty" objects ("bsize"+1 bytes).
  309. - The bitmap area in a "button" or "message" with a bitmap.
  310. - For a window that is in the screen and covering others, the window area
  311.   (contained in the "frame" attribute "areaw", valid when "Pw" is not nil).
  312.   Images of window backgrounds and bitmaps are saved in "figstruct" records
  313. or structures.
  314.   Programs that use dynamic allocation of objects shall contain object
  315. "destructors". A "destructor" is a procedure that deallocates the four
  316. first items listed above when the corresponding objects are "destroyed".
  317. The most usual procedure is to use a "destructor" as the "notify_handler"
  318. of a window "frame". In this way, the "destructor" is automatically called
  319. when the window is closed, and deallocates all its objects. The window area
  320. is automatically freed when the window is closed. New windows are created
  321. normally with calls to "xv_create". Note that the procedures "xv_create"
  322. and "item_create" allocate memory, and so can fail if there is not enough
  323. heap memory. See the example program XBITMAP.PAS for an example of how to
  324. use dynamic allocation.
  325.   Heap memory for the program can be allocated or deallocated at any
  326. moment. The Turbo Pascal  "Mark" and "Release" functions cannot be used.
  327.  
  328. COLORS AND GRAPHICS MODES
  329. -------------------------
  330.  
  331.   All the graphics boards and modes supported by the BGI drivers are
  332. accepted. The default colors are used in the EGA and VGA boards. In modes
  333. with two colors, a pattern of black and white dots is used in place of the
  334. gray color in the objects. The colors can be changed changing some global
  335. constants, or changing the palette.
  336.  
  337. SOME RECOMMENDATIONS
  338. --------------------
  339.  
  340.   Use the "X_Make" program to generate the initial version of an interface,
  341. editting it as needed after to fill the "callbacks" and other alterations.
  342. Keep the structure that "X_Make" generates.
  343.   Note that some objects that are never referenced, as buttons, must not be
  344. declared separately. "X_Make" declares all the objects for clarity.
  345.   Do not use dynamic object allocation, windows with exclusive access, or
  346. interposition unnecessarily.
  347.   Keep rigorously the philosophy that the commands in the windows can be
  348. acessed at any instant. The most that the program shall do to impede access
  349. to an object is to close the window that contains it.
  350.   Verify carefully the effects of commands given by the user out of the
  351. expected order. Make the program warn the user in these cases and recommend
  352. the correct action.
  353.   Warnings of possibly incorrect or dangerous operations, asking for immediate
  354. confirmation, are valid uses for windows with exclusive access.
  355.   Make a window as the main window, putting it over the background and
  356. impeding its closing with the mouse (<frame>^.adjust_exit:=FALSE).
  357.   Use smaller windows for dialog with the user. At least one window shall
  358. contain a "tty", used for messages to the user, listings, etc.
  359.   Create a menu, always accesible, that opens any of the program windows. It
  360. is the simplest mean to avoid possible "deadlocks" in a complex program.
  361.  
  362. FILES, COMPILATION, AND DIRECTORIES
  363. -----------------------------------
  364.  
  365.   For compilation, the files XVIEW.TPU and MICKEY.TPU (or the equivalent
  366. .TPP files for protected mode programs) must be accessible for the
  367. compilation in Turbo Pascal (Version 7.0). The C version uses the files
  368. XVIEW.H, MICKEY.H, and the corresponding .OBJ files.
  369.   For execution, the BGI driver and the font LITT.CHR must be in the local
  370. directory, or in a path pointed by the DOS environment variable TPBGI.
  371. Bitmaps used in buttons or messages, or drawn by the "drawbitmap" routine,
  372. must be in the local directory, or in a path pointed by the DOS environment
  373. variable BMP.
  374.   For compilation in C/C++, see instructions in the file XVIEW.H.
  375.  
  376. LICENSING AND USE OF THE XVIEW-PC INTERFACE
  377. -------------------------------------------
  378.  
  379.   The use of the interface is free for educational and academic purposes,
  380. not commercial. The compressed file XV_PC*.ZIP can be distributed freely,
  381. respected these restrictions, and that it cannot be changed in any way
  382. without the consent of the author.
  383.   The code is offered "as is". The author believes that everything is working
  384. correctly, but cannot be responsible for eventual losses caused by
  385. imperfections or bugs in the code.
  386.   For the clarifying of doubts, information about detected problems, or
  387. information about licensing for commercial use or source code, the interested
  388. shall contact the author:
  389.  
  390. Dr. Antonio Carlos Moreirao de Queiroz
  391. COPPE/UFRJ - Programa de Engenharia Eletrica
  392. CP 68504
  393. 21945-970 Rio de Janeiro, RJ, Brasil
  394. e-mail: acmq@coe.ufrj.br
  395.  
  396. CONSTANTS AND VARIABLES DEFINED IN THE XVIEW UNIT AND .H INCLUDE FILE
  397. ---------------------------------------------------------------------
  398.  
  399.   This is a translation of the unit header XVIEW.INT, that is commented in
  400. Portuguese.
  401.   The variables below marked with "#" are object parameters that usually
  402. are changed immediately after the object creation. All have safe default
  403. values.
  404.   The variables marked with "*" are reserved for internal use, and shall
  405. not be modified in the normal interface operation.
  406.   The others can be changed at any moment.
  407.   The constants, types, and variables are listed in Pascal notation. The C
  408. versions are equivalent. See the actual headers in the .INT and .H files
  409. (with comments in Portuguese in the Pascal version) for details.
  410.   The main difference in the C versions is the way how the object fields are
  411. accessed. See the examples and the code generated by the X_MAKE program.
  412.  
  413. CONST
  414. LOC_MOVE=256;    {event: mouse moved}
  415. LOC_DRAG=257;    {event: mouse moved with pressed button(s)}
  416. MS_LEFT=1001;    {event: left mouse button pressed}
  417. MS_MIDDLE=1004;  {event: middle mouse button pressed}
  418. MS_RIGHT=1002;   {event: right mouse button pressed}
  419. m_itens=20;      {maximum number of items in menus and setting (only 16 in
  420. these)}
  421. m_chars=60;      {characters in strings}
  422. mrgx=5;          {lateral and bottom window margins}
  423. mrgy=22;         {upper window margin}
  424.  
  425. CONST
  426. normal_bsize:WORD=1000;   {"bsize" (tty) attributed by "xv_create"}
  427. normal_length:INTEGER=16; {"value_length" (textfield) attributed by
  428. "xv_create"}
  429. wallpaper:BOOLEAN=FALSE;       {if the screen background is retained}
  430. c_normal:INTEGER=lightgray;    {color of object background}
  431. c_active:INTEGER=green;        {color of pressed buttons}
  432. c_light:INTEGER=white;         {color of lighted corners}
  433. c_shadow:INTEGER=black;        {color of shadowed corners}
  434. c_white:INTEGER=white;         {default "back_color"}
  435. c_black:INTEGER=black;         {default "fore_color"}
  436. c_overwrite:INTEGER=lightred;  {edition color for "textfields"}
  437. c_edit:INTEGER=blue;           {selection color for "textfields"}
  438. c_insert:INTEGER=yellow;       {insertion color for "textfields"}
  439. c_hatch:INTEGER=cyan;          {color of the background pattern}
  440. type_hatch:INTEGER=XHatchFill; {type of the background pattern}
  441. use_palette:BOOLEAN=TRUE;      {if the bitmap palettes are used}
  442. normal_client_data:POINTER=nil;{"client_data" attributed by "xv_create"}
  443. nlines:INTEGER=60;             {* number of lines in each image block}
  444.  
  445. TYPE
  446. figstruct=RECORD                     {structure for images}
  447.   blocks:INTEGER;                    {number of image blocks-1}
  448.   blocksize,lastblocksize:WORD;      {size of the allocated image blocks}
  449.   v:ARRAY[0..2000] of POINTER;       {only allocated until "blocks"}
  450. END;
  451. ptrfig=^figstruct;                   {image pointer}
  452. Xv_opaque=^xv_widget;                {generic object}
  453. xv_handler=PROCEDURE(pt:Xv_opaque);  {"callback" procedure}
  454. xv_label_type=STRING[m_chars];       {all strings}
  455. tty_buffer=ARRAY[0..65534] OF CHAR;  {"tty" buffer. Only "bsize"+1 bytes
  456. are allocated and used}
  457. xv_package=(frame,button,textfield,setting,message,canvas,tty,menu);
  458. xv_widget=RECORD
  459.   {Parameters used in all the objects}
  460.   xv_label:xv_label_type;         {# title}
  461.   x,y,dx,dy:INTEGER;              {# position and size}
  462.   fore_color,back_color:INTEGER;  {# colors}
  463.   owner:Xv_opaque;                {* owner "frame"}
  464.   next:Xv_opaque;                 {* next object}
  465.   menu_name:Xv_opaque;            {# associated menu}
  466.   notify_handler:xv_handler;      {# associated notify handler}
  467.   event_handler:xv_handler;       {# associated event handler}
  468.   client_data:POINTER;            {# pointer to other parameters}
  469.   {Specific parameters for each object}
  470.   CASE o_type:xv_package OF       {* object type}
  471.     frame:(over,under:Xv_opaque;  {* neighbor windows}
  472.       Pw:ptrfig;                  {* covered image}
  473.       areaw:LONGINT;              {* window area size}
  474.       dxmin,dymin:INTEGER;        {# minimum dimensions}
  475.       interfere:BOOLEAN;          {* internal use}
  476.       mapped:BOOLEAN;             {* if it is on the screen}
  477.       adjust_exit:BOOLEAN;        {# if central button can close}
  478.       mouse_obj:Xv_opaque;        {# object pointed by the mouse when the
  479. window is opened. nil if none (default)}
  480.       gr_out:ViewPortType);       {* associated "ViewPort"}
  481.     button:(icon_label:BOOLEAN;   {# if "xv_label" is a file name}
  482.       Pimageb:ptrfig);            {* button bitmap}
  483.     message:(icon_msg:BOOLEAN;    {# if "xv_label" is a file name}
  484.       Pimagem:ptrfig);            {* message bitmap}
  485.     textfield:(panel_value:xv_label_type;  {# text value}
  486.       panel_real:REAL;            {# real value}
  487.       panel_int:INTEGER;          {# integer value}
  488.       min_value,max_value:INTEGER;{# limits for integers}
  489.       value_length:INTEGER;       {# edition field length}
  490.       field_type:(text_field,real_field,int_field)); {# type}
  491.     setting:(itens_setting:INTEGER; {* number of itens}
  492.       sel_setting:INTEGER;          {# selection}
  493.       item_setting:array[1..m_itens] OF ^xv_label_type;{* item names}
  494.       exclusive:BOOLEAN);           {# if the selection is exclusive}
  495.     canvas:(can_xext,can_yext:BOOLEAN);  {# if the "canvas" extends to the
  496. window borders}
  497.     tty:(tty_xext,tty_yext:BOOLEAN; {# if the "tty" extends to the window
  498. borders}
  499.       xc,yc:INTEGER;    {* graphical cursors}
  500.       bsize:WORD;       {* buffer size}
  501.       bstart:WORD;      {* buffer start}
  502.       tstart:WORD;      {* visible text start}
  503.       bcsr:WORD;        {* visible text end}
  504.       tend:WORD;        {* text end+1}
  505.       dxtty:INTEGER;    {* panel width}
  506.       Pb:^tty_buffer);  {* buffer pointer}
  507.     menu:(itens_menu:INTEGER; {* number of items}
  508.       sel_menu:INTEGER;       {# selected item}
  509.       item_menu:ARRAY[1..m_itens] OF ^xv_label_type; {* item names}
  510.       item_submenu:ARRAY[1..m_itens] OF Xv_opaque);  {# submenus}
  511.   END;
  512.  
  513. VAR
  514.   insert:BOOLEAN;          {if text is inserted in "textfields"}
  515.   xv_end:BOOLEAN;          {ends "xv_main_loop"}
  516.   ulttxt:xv_label_type;    {last text entered in "textfields"}
  517.   xv_ok:BOOLEAN;           {* result of the last window operation}
  518.   ie_locx,ie_locy:INTEGER; {* mouse position relative to active object or
  519. window}
  520.   ie_code:INTEGER;         {* event code}
  521.   ie_shiftcode:INTEGER;    {* mouse buttons state}
  522.   active_w:Xv_opaque;      {* the active window "frame"}
  523.   active_o:Xv_opaque;      {* active object}
  524.   w_base:Xv_opaque;        {* base window for "xv_create"}
  525.   o_base:Xv_opaque;        {* base object for"item_create"}
  526.   redrawing_frame:BOOLEAN; {* if a window is being redrawn}
  527.   interposer:PROCEDURE;    {routine called after each event}
  528.  
  529. {Public subroutines. Only the first four are of essential use}
  530.  
  531. PROCEDURE xv_init(board,mode:INTEGER);
  532. {General initialization. Enters the specified graphics mode, initializes
  533. colors and mouse, and sets "active_w" to "nil"}
  534.  
  535. FUNCTION xv_create(obj_type:xv_package):Xv_opaque;
  536. {Allocates and initializes with default values an object. Returns its
  537. "handle" pointer.
  538. Allocates the buffer "tty_buffer" of "tty" objects, with
  539. "GetMem(Pb,bsize+1)".
  540. Must be called once for each object, beginning by the window "frame".
  541. Does not test possible "heap overflow"}
  542.  
  543. PROCEDURE item_create(txt:xv_label_type);
  544. {Creates "menu" or "setting" items.
  545. Call once for each item, immediately after "xv_create". The items are
  546. enumerated from 1. In the Pascal version, the texts are allocated with
  547. GetMem(<item>,Length(txt)+1). In the C versions, nothing is allocated.
  548. Does not test "heap overflow"}
  549.  
  550. PROCEDURE xv_main_loop(w:Xv_opaque);
  551. {Opens a window and starts the cycle wait for event - process event.
  552. Ends when all the windows are closed or when "xv_end" is true.
  553. Does not deallocates the objects at exit.
  554. Can be called more than once to create a special window. See the files
  555. EXCLUSIV.INC and NOTICE.H for examples.}
  556.  
  557. PROCEDURE open_window(w:Xv_opaque);
  558. {Opens a window, turning it the active one.
  559. The selected window is opened and/or put in the foreground.
  560. Causes calls to "canvas" "notify_handlers" if the window is not in the
  561. screen.
  562. Can be called at any time after "xv_init". Calls before "xv_main_loop" can
  563. be used to start a program with several open windows}
  564.  
  565. PROCEDURE close_window(w:Xv_opaque);
  566. {Closes a window. Causes a call to the "frame" "notify_handler", if
  567. installed. Can also be called at any moment after "xv_init". The window is
  568. moved to the foreground and erased. The window objects are kept allocated}
  569.  
  570. PROCEDURE ttysw_output(terminal:Xv_opaque; text:STRING);
  571. {Writes a text in a "tty" terminal. The "tty" window is opened and turned
  572. the active window}
  573.  
  574. PROCEDURE back;
  575. {Circulates back the windows, moving the present active window to the
  576. background. Useful in window menus}
  577.  
  578. PROCEDURE xv_set(obj:Xv_opaque; new_label:xv_label_type);
  579. {Changes the "xv_label" of an object. The window object is turned the
  580. active window. Mainly used to change "messages". Can be used to update also
  581. other parameters, as "textfield" values, directly set before the call}
  582.  
  583. PROCEDURE menu_show(obj:Xv_opaque);
  584. {Opens a menu at the mouse location (mousex, mousey). It is better to
  585. associate menus to the objects. This is the routine used internally to open
  586. menus. A typical use is to make a button open a menu, by calling
  587. "menu_show" from the button "notify_handler"}
  588.  
  589. PROCEDURE draw_object(obj:Xv_opaque; active:BOOLEAN);
  590. {Draws an object. Can be used causing the fast redraw of a window (use the
  591. "frame" as parameter), as a more powerful version of "xv_set". "active"
  592. affects only buttons. For objects that are not "frames", the background is
  593. not erased, and labels are only drawn if the global variable
  594. "redrawing_frame" is true. This routine is used internally. Its use is not
  595. recommended}
  596.  
  597. PROCEDURE Nothing(obj:Xv_opaque);
  598. {Default "notify_handler" and "event_handler". No action. Can be used to
  599. inactivate "callbacks"(unusual)}
  600.  
  601. PROCEDURE nointerpose;
  602. {Default "interposer". No action. Can be used to inactivate the "interposer"}
  603.  
  604. PROCEDURE wait_button;
  605. {Waits until the mouse buttons are released (unusual).}
  606.  
  607. FUNCTION Cpct(x:REAL):STRING;
  608. {Returns a more compact form of a real number (Pascal version only)}
  609.  
  610. PROCEDURE DrawBitmap(x,y:INTEGER; VAR dw,dh:INTEGER; VAR Pimg:POINTER;
  611. filename:xv_label_type);
  612. {Draws a Windows 16 colors bitmap at (x, y).
  613. If "Pmgi=nil", loads the bitmap from disk (BMP format) and, if possible,
  614. allocates memory and saves it in "Pimg^" as a "figstruct" structure.
  615. Posterior calls cause a faster drawing. The used memory is
  616. "FigureSize(0,0,dw,dh)" bytes.
  617. The dimensions "dw" and "dh" are returned (width-1 and height-1).
  618. It is used internally to draw "buttons" and "messages" with images.
  619. "Pimg" can be the address of another "figstruct" variable.
  620. Note that, as "PutImage" does not clips at the "viewport" limits, the
  621. window that contains bitmaps must be always of enough size to contain them}
  622.  
  623. {The routines below are used internally in operations involving images.
  624. They are also available for other uses}
  625.  
  626. FUNCTION FigureSize(x1,y1,x2,y2:INTEGER):LONGINT;
  627. {Memory needed for an image. Size of the "figstruct" structure}
  628.  
  629. PROCEDURE GetFigureMem(VAR p:ptrfig; dw,dh:INTEGER);
  630. {Allocates memory for an image. "dw" and "dh" are width-1 and height-1}
  631.  
  632. PROCEDURE FreeFigureMem(p:ptrfig);
  633. {Frees memory allocated previously with "GetFigureMem"}
  634.  
  635. PROCEDURE GetFigure(x1,y1,x2,y2:INTEGER; p:ptrfig);
  636. {Captures an image from the screen. "ptrfig" must be allocated with
  637. "GetFigureMem" before the call}
  638.  
  639. PROCEDURE PutFigure(x,y:INTEGER; p:ptrfig; bitblt:WORD);
  640. {Draws an image captured with "GetFigure" at (x, y) in the screen}
  641.  
  642. THE MOUSE DRIVER (MICKEY MODULE)
  643. --------------------------------
  644.  
  645.   The MICKEY unit or object file implements the mouse functions of the
  646. interface. Normally it is not necessary for a program to use the mouse
  647. functions directly, but they are available.
  648.   If the mouse is not installed, the keyboard emulates it. The cursor moves
  649. the arrow, and the buttons are substituted by:
  650.   left:    Return
  651.   central: Escape
  652.   right:   Space
  653.   The keys Home, PgDn, and PgUp change the cursor step.
  654.   With CapsLock or Shift (in the Pascal version) active, the buttons work
  655. in toggle mode.
  656.   ScrollLock suspends the emulation when active, allowing normal use of the
  657. keyboard.
  658.   The unit can be used alone. For the correct working of the emulator, the
  659. function "mouse_read" must be called regularly.
  660.   Below are listed the available variables and procedures, in Pascal
  661. notation. It is a translation of the unit header MICKEY.INT, commented in
  662. Portuguese. The C versions are identical.
  663.  
  664. CONSTANTS AND VARIABLES DEFINED IN THE MICKEY UNIT AND .H INCLUDE FILE
  665. ----------------------------------------------------------------------
  666.  
  667. VAR
  668.   mousex,mousey,mouseb,x_factor:INTEGER; {mouse state}
  669.   cursor_active:BOOLEAN;
  670.  
  671. PROCEDURE mouse_init;              {Initialization}
  672. PROCEDURE cursor_on;               {Cursor on}
  673. PROCEDURE cursor_off;              {Cursor off}
  674. PROCEDURE mouse_read;              {Reads current state}
  675. PROCEDURE mouse_move(x,y:INTEGER); {Moves cursor}
  676. FUNCTION  mkbhit:BOOLEAN;          {Identical to KeyPressed (of kbhit), but
  677.                     do not report keys used by the mouse
  678.                     emulator, when active. Internal use}
  679.  
  680. WHAT IS NEW
  681. -----------
  682.  
  683. Version 1.6: First version distributed to the Internet, December 1993.
  684.  
  685. Version 1.6a: April 1994.
  686.   - Keys with extended codes generate only one event (2000+2nd code).
  687.     This is the only change that may cause some changes in programs written
  688.     for the previous version.
  689.   - A version of the C object files compatible with C++ was added.
  690.   - The C versions were compiled with the "huge" model.
  691.   - The functions "kbhit()" (C), and "KeyPressed" (Pascal) now function
  692.     normally. The function "mkbhit" shall be used instead of them.
  693.   - When the mouse emulator is active, only the events used by it are not
  694.     generated (arrows, home, pgup, pgdn, cr, space, and esc).
  695.   - The documentation of the C version and all examples was translated to
  696.     English.
  697.   - Small bugs in the "textfield" editor (C version), in menu operations,
  698.     and in the "tty" were corrected.
  699.   - Word alignment is not necessary anymore.
  700.   - The "interposer" was included.
  701.   - The "textfield" editor and the Cpct function (Pascal) were modified.
  702.   - Source files with some utilities and examples were added (extkeys,
  703.     notice, exclusiv, hotkeys, tabkeys, rotor).
  704.  
  705. ACMQ - 26/04/94
  706.